{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#  Convolutional Neural Network\n",
    "\n",
    "### Convolutional Layers: [256,256] ; Dense Layers [256] \n",
    "\n",
    "CNN is trained on raw data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Get the data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Stored variables and their in-db values:\n",
      "X_test              -> defaultdict(<class 'list'>, {0: array([[[-0.000890\n",
      "X_train             -> array([[[  4.08058986e-03,   2.41095549e-03,   6.0\n",
      "snrs                -> [-20, -18, -16, -14, -12, -10, -8, -6, -4, -2, 0, \n",
      "y_test              -> defaultdict(<class 'list'>, {0: array([5, 2, 6, ..\n",
      "y_train             -> array([5, 3, 0, ..., 6, 0, 3])\n"
     ]
    }
   ],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from collections import defaultdict\n",
    "from time import time\n",
    "\n",
    "%store -r\n",
    "%store"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training data:  (80000, 2, 128) and labels:  (80000,)\n",
      "\n",
      "Test data:\n",
      "Total 20 (4000, 2, 128) arrays for SNR values:\n",
      "[-20, -18, -16, -14, -12, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18]\n"
     ]
    }
   ],
   "source": [
    "print(\"Training data: \", X_train.shape, \"and labels: \", y_train.shape)\n",
    "print()\n",
    "print(\"Test data:\")\n",
    "print(\"Total\", len(X_test), X_test[18].shape, \"arrays for SNR values:\")\n",
    "print(sorted(X_test.keys()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Standardize the features"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training set (80000, 2, 128)\n",
      "Test set corresponding to one snr value (4000, 2, 128)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "sc = StandardScaler()\n",
    "_X_train = np.reshape(X_train, [X_train.shape[0], X_train.shape[1]*X_train.shape[2]])\n",
    "_X_train = sc.fit_transform(_X_train)\n",
    "\n",
    "X_train = np.reshape(_X_train, X_train.shape)\n",
    "print(\"Training set\", X_train.shape)\n",
    "\n",
    "_X_test = defaultdict(list)\n",
    "for snr in snrs:\n",
    "    _X_test[snr] = np.reshape(X_test[snr], [X_test[snr].shape[0], X_test[snr].shape[1]*X_test[snr].shape[2]])\n",
    "    _X_test[snr] = sc.transform(_X_test[snr])\n",
    "    X_test[snr] = np.reshape(_X_test[snr], X_test[snr].shape)\n",
    "    \n",
    "print(\"Test set corresponding to one snr value\", X_test[18].shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Design and train the CNN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 0 training accuracy : 0.279296875\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0\n",
      "Epoch 1 training accuracy : 0.3623046875\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0\n",
      "Epoch 2 training accuracy : 0.43359375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0\n",
      "Epoch 3 training accuracy : 0.53515625\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0\n",
      "Epoch 4 training accuracy : 0.541015625\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0\n",
      "Epoch 5 training accuracy : 0.5927734375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0\n",
      "Epoch 6 training accuracy : 0.650390625\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0\n",
      "Epoch 7 training accuracy : 0.6474609375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0\n",
      "Epoch 8 training accuracy : 0.6787109375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0\n",
      "Epoch 9 training accuracy : 0.6923828125\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0\n",
      "Training took 62.265401 minutes\n"
     ]
    }
   ],
   "source": [
    "height = 2\n",
    "width = 128\n",
    "channels = 1\n",
    "n_features = height * width\n",
    "\n",
    "feature_map1 = 256\n",
    "ksize_conv1 = 2\n",
    "stride_conv1 = 1\n",
    "\n",
    "feature_map2 = 256\n",
    "ksize_conv2 = ksize_conv1\n",
    "stride_conv2 = stride_conv1\n",
    "\n",
    "pool_layer_maps2 = feature_map2\n",
    "\n",
    "n_fully_conn1 = 256\n",
    "\n",
    "n_classes = 8\n",
    "  \n",
    "X = tf.placeholder(tf.float32, shape=[None, height, width])\n",
    "X_reshaped = tf.reshape(X, shape=[-1, height, width, channels])\n",
    "labels = tf.placeholder(tf.int32, shape=[None])\n",
    "training_ = tf.placeholder_with_default(False, shape=[])\n",
    "\n",
    "xavier_init = tf.contrib.layers.xavier_initializer()\n",
    "relu_act = tf.nn.relu\n",
    "\n",
    "# ------------------ Convolutional and pooling layers ----------------------------\n",
    "\n",
    "def convolutional_layer(X, filter_, ksize, kernel_init, strides, padding):\n",
    "    convolutional_layer = tf.layers.conv2d(X, filters = filter_, kernel_initializer = kernel_init,\n",
    "                                           kernel_size = ksize, strides = strides,\n",
    "                                          padding = padding, activation = relu_act)\n",
    "    return convolutional_layer\n",
    "\n",
    "def pool_layer(convlayer, ksize, strides, padding, pool_maps):\n",
    "    pool = tf.nn.max_pool(convlayer, ksize, strides, padding)\n",
    "    dim1, dim2 = int(pool.get_shape()[1]), int(pool.get_shape()[2])\n",
    "    pool_flat = tf.reshape(pool, shape = [-1, pool_maps * dim1 * dim2])\n",
    "    return pool_flat\n",
    "\n",
    "conv_layer1 = convolutional_layer(X_reshaped, feature_map1, ksize_conv1, xavier_init, stride_conv1, padding = \"SAME\")\n",
    "\n",
    "conv_layer2 = convolutional_layer(conv_layer1, feature_map2, ksize_conv2, xavier_init, stride_conv2, padding = \"SAME\")\n",
    "\n",
    "pool_layer2_flat = pool_layer(conv_layer2, [1,2,2,1], [1,2,2,1], \"VALID\", pool_layer_maps2)\n",
    "\n",
    "# ----------------- Fully connected and dropout layers -------------------\n",
    "\n",
    "def dense_layer(input_layer, n_neurons, kernel_init, activation):\n",
    "    fully_conn = tf.layers.dense(inputs = input_layer, units = n_neurons, activation = activation,\n",
    "                                kernel_initializer = kernel_init)\n",
    "    return fully_conn\n",
    "        \n",
    "dense_layer1 = dense_layer(pool_layer2_flat, n_fully_conn1, xavier_init, relu_act)\n",
    "\n",
    "# ----------------- Output softmax layer ---------------------------\n",
    "\n",
    "logits = tf.layers.dense(dense_layer1, n_classes)\n",
    "softmax_activations = tf.nn.softmax(logits)\n",
    "\n",
    "# ----------------- Specify performance measure -------------------------------\n",
    "\n",
    "cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits = logits, labels = labels)\n",
    "loss = tf.reduce_mean(cross_entropy)\n",
    "optimizer = tf.train.AdamOptimizer()\n",
    "train_operation = optimizer.minimize(loss)\n",
    "\n",
    "correct_predictions = tf.nn.in_top_k(logits, labels, 1)\n",
    "accuracy = tf.reduce_mean(tf.cast(correct_predictions, tf.float32))\n",
    "\n",
    "# ---------------- Execution phase -------------------------------------------\n",
    "    \n",
    "n_epochs = 10\n",
    "batch_size = 1024\n",
    "n_train = X_train.shape[0]\n",
    "n_iter = n_train//batch_size\n",
    "\n",
    "acc_test = defaultdict(list)\n",
    "\n",
    "path = \"./CNN_2conv_1dense.0\"  \n",
    "saver = tf.train.Saver()\n",
    "\n",
    "start = time()\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    tf.global_variables_initializer().run()\n",
    "    for epoch in range(n_epochs):\n",
    "        for iteration in range(n_iter):\n",
    "            rand_indices = np.random.choice(n_train,batch_size)    \n",
    "            X_batch, y_batch = X_train[rand_indices], y_train[rand_indices]\n",
    "            sess.run(train_operation, feed_dict={X: X_batch, labels: y_batch, training_: True})\n",
    "        acc_train = accuracy.eval(feed_dict={X: X_batch, labels: y_batch})\n",
    "        print(\"Epoch {} training accuracy : {}\".format(epoch, acc_train))\n",
    "        save_path = saver.save(sess, path)\n",
    "        saver.restore(sess, path)\n",
    "    saver.restore(sess, path)\n",
    "    for snr in snrs:\n",
    "        acc_test[snr] = accuracy.eval(feed_dict={X: X_test[snr], labels: y_test[snr]})\n",
    "\n",
    "print(\"Training took %f minutes\"%(float(time() - start)/60.0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Test the classifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CNN's test accuracy on -20dB SNR samples = 0.12025000154972076\n",
      "CNN's test accuracy on -18dB SNR samples = 0.1262499988079071\n",
      "CNN's test accuracy on -16dB SNR samples = 0.11924999952316284\n",
      "CNN's test accuracy on -14dB SNR samples = 0.14350000023841858\n",
      "CNN's test accuracy on -12dB SNR samples = 0.16249999403953552\n",
      "CNN's test accuracy on -10dB SNR samples = 0.18950000405311584\n",
      "CNN's test accuracy on -8dB SNR samples = 0.25174999237060547\n",
      "CNN's test accuracy on -6dB SNR samples = 0.335999995470047\n",
      "CNN's test accuracy on -4dB SNR samples = 0.46549999713897705\n",
      "CNN's test accuracy on -2dB SNR samples = 0.6302499771118164\n",
      "CNN's test accuracy on 0dB SNR samples = 0.71875\n",
      "CNN's test accuracy on 2dB SNR samples = 0.762499988079071\n",
      "CNN's test accuracy on 4dB SNR samples = 0.7837499976158142\n",
      "CNN's test accuracy on 6dB SNR samples = 0.7777500152587891\n",
      "CNN's test accuracy on 8dB SNR samples = 0.7867500185966492\n",
      "CNN's test accuracy on 10dB SNR samples = 0.8017500042915344\n",
      "CNN's test accuracy on 12dB SNR samples = 0.7997499704360962\n",
      "CNN's test accuracy on 14dB SNR samples = 0.7872499823570251\n",
      "CNN's test accuracy on 16dB SNR samples = 0.7944999933242798\n",
      "CNN's test accuracy on 18dB SNR samples = 0.7907500267028809\n"
     ]
    }
   ],
   "source": [
    "for snr in snrs:\n",
    "    print(\"CNN's test accuracy on {}dB SNR samples = {}\".format(snr,acc_test[snr]))  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Visualize classifier's performance on test set"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fdc9c0430b8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.style.use('classic')\n",
    "%matplotlib inline\n",
    "\n",
    "acc_test = sorted(acc_test.items())\n",
    "new_acc = []\n",
    "for i in range(len(acc_test)):\n",
    "    new_acc.append(acc_test[i][1])\n",
    "acc_test_values = new_acc \n",
    "\n",
    "fig1 = plt.figure(figsize=(10, 6), dpi=100)\n",
    "x = snrs\n",
    "y = list(acc_test_values)\n",
    "plt.plot(x, y, marker=\"o\", linewidth=2.0, linestyle='dashed', color='royalblue')\n",
    "plt.axis([-20, 20, 0, 1])\n",
    "plt.xticks(np.arange(min(x), max(x)+1, 2.0))\n",
    "plt.yticks(np.arange(0, 1, 0.10))\n",
    "\n",
    "ttl = plt.title('SNR vs Accuracy', fontsize=16)\n",
    "ttl.set_weight('bold')\n",
    "plt.xlabel('SNR (dB)', fontsize=14)\n",
    "plt.ylabel('Test accuracy', fontsize=14)\n",
    "plt.grid()\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Restoring parameters from ./CNN_2conv_1dense.0\n",
      "Confusion Matrix\n",
      "       8PSK  BPSK  CPFSK  GFSK  PAM4  QAM16  QAM64  QPSK\n",
      "8PSK   0.65  0.00   0.01  0.00  0.00   0.09   0.08  0.16\n",
      "BPSK   0.00  0.96   0.00  0.00  0.02   0.01   0.00  0.01\n",
      "CPFSK  0.01  0.00   0.96  0.01  0.00   0.00   0.00  0.01\n",
      "GFSK   0.00  0.00   0.01  0.98  0.00   0.00   0.00  0.00\n",
      "PAM4   0.00  0.00   0.00  0.00  0.99   0.00   0.00  0.00\n",
      "QAM16  0.04  0.00   0.00  0.00  0.00   0.47   0.48  0.01\n",
      "QAM64  0.02  0.00   0.00  0.00  0.00   0.47   0.50  0.01\n",
      "QPSK   0.19  0.01   0.00  0.00  0.00   0.04   0.02  0.74\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7fdc91d44588>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Confusion Matrix\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    saver.restore(sess, path)\n",
    "    Z = logits.eval(feed_dict = {X : X_test[18]})\n",
    "    predicted_18dB = np.argmax(Z, axis = 1)\n",
    "    \n",
    "from sklearn.metrics import confusion_matrix\n",
    "%matplotlib inline\n",
    "\n",
    "classes = ['8PSK', 'BPSK', 'CPFSK', 'GFSK', 'PAM4', 'QAM16', 'QAM64', 'QPSK']\n",
    "conf_matrix = confusion_matrix(predicted_18dB, y_test[18])  \n",
    "\n",
    "conf_matrix = conf_matrix.astype('float') / conf_matrix.sum(axis=1)[:, np.newaxis]\n",
    "conf_matrix = conf_matrix.round(decimals = 2)\n",
    "\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame(data = conf_matrix, columns = classes, index = classes) \n",
    "print(\"Confusion Matrix\")\n",
    "print(df)\n",
    "\n",
    "fig1 = plt.figure(figsize=(10, 6), dpi=100)\n",
    "plt.imshow(conf_matrix, interpolation = 'nearest', cmap = plt.cm.Purples)\n",
    "ticks = np.arange(len(classes))\n",
    "plt.title(\"Confusion Matrix\")\n",
    "plt.xticks(ticks, classes, rotation=45)\n",
    "plt.yticks(ticks, classes)\n",
    "\n",
    "plt.ylabel('True class')\n",
    "plt.xlabel('Predicted class')\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.colorbar()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
